package com.wsk.controller;

import com.alibaba.druid.util.StringUtils;
import com.wsk.util.VerifyCodeUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;

/**
 * Created by wsk1103 on 2017/9/15.
 */
@Controller
@RequestMapping(value = "/mydemo")
public class LoginController {
    //获取验证码图片和文本（验证码文本保存在HttpSession中）
    @RequestMapping(value = "/getVerifyCodeImage")
    public void getVerifyCodeImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //设置页面不缓存
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        //将验证码存放到HttpSession里面
        String verifyCode = VerifyCodeUtil.generateTextCode(VerifyCodeUtil.TYPE_ALL_MIXED, 4, null);
        request.getSession().setAttribute("verifyCode", verifyCode);
        System.out.println("验证码为：" + verifyCode);
        //设置输出的内容类型为JPEG图像
        response.setContentType("image/jpeg");
        BufferedImage bufferedImage = VerifyCodeUtil.generateImageCode(verifyCode, 90, 30, 3, true, Color.white, Color.black, null);
        //写给浏览器
        ImageIO.write(bufferedImage, "JPEG", response.getOutputStream());
    }

    //用户登录
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login(HttpServletRequest request) {
        String resultPageURL = InternalResourceViewResolver.FORWARD_URL_PREFIX + "/";
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        // 获取HttpSeesion中的验证码
        String verifyCode = (String) request.getSession().getAttribute("verifyCode");
        //获取用户请求表单中输入的验证码
        String submitCode = WebUtils.getCleanParam(request, "verifyCode");
        System.out.println("用户[" + username + "]登录时输入的验证码为[" + submitCode + "],HttpSession中的验证码为[" + verifyCode + "]");
        if (StringUtils.isEmpty(submitCode) || !StringUtils.equals(verifyCode, submitCode.toLowerCase())) {
            request.setAttribute("message_login", "验证码错误");
            return resultPageURL;
        }
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        token.setRememberMe(true);
        System.out.println("token为:"+token);
        //获取当前的subject
        Subject currentUser = SecurityUtils.getSubject();
        try {
            //在调用login方法后，securityManager会收到AuthenticationToken，并将其发送给已配置的Realm
            //执行必须的认证检查
            //每个Realm都能在必要的时对提交的AuthenticationTokens做出反应
            //所以这一步调用login(token)方法时，它会走到MyRealm.doGetAuthenticationInfo()方法中。
            System.out.println("对用户[" + username + "]验证开始。。。。。。。。。");
            currentUser.login(token);
            System.out.println("对用户[" + username + "]验证结束。。。。。。。。。。通过");
            resultPageURL = "main";
        } catch (UnknownAccountException e) {
            System.out.println("未知用户");
            request.setAttribute("message_login", "未知账号");
        } catch (IncorrectCredentialsException e) {
            System.out.println("密码错误");
            request.setAttribute("message_login", "密码错误");
        } catch (LockedAccountException e) {
            System.out.println("账号锁定");
            request.setAttribute("message_login", "账号锁定");
        } catch (ExcessiveAttemptsException e) {
            System.out.println("错误次数过多");
            request.setAttribute("message_login", "用户名/密码错误次数过多");
        } catch (AuthenticationException e) {
            //通过处理shiro的运行时AuthenticationException就可以控制用户登录失败的场景
            System.out.println("堆栈轨迹如下：");
            e.printStackTrace();
            request.setAttribute("message_login","用户名/密码错误");
        }
        //验证是否登录成功
        if (currentUser.isAuthenticated()){
            System.out.println("用户["+username+"]登录通过，初始化开始。。。。。");
        } else {
            token.clear();
        }
        return resultPageURL;
    }

    //用户退出
    @RequestMapping(value = "/logout")
    public String logout() {
        SecurityUtils.getSubject().logout();
        return InternalResourceViewResolver.REDIRECT_URL_PREFIX + "/";
    }
}
